<template>
    <div class="QilinUploadFile">
        <el-upload
            ref="uploadFileRef"
            :action="ownUploadFileConfig.action || '#' "
            :headers="ownUploadFileConfig.headers || {}"
            :list-type="ownUploadFileConfig.listType || 'text' "
            :auto-upload="ownUploadFileConfig.autoUpload || false "
            :limit="ownUploadFileConfig.limit || 5"
            :drag="ownUploadFileConfig.drag ?? true "
            :file-list="ownUploadFileConfig.fileList || [] "
            :multiple="ownUploadFileConfig.multiple ?? true "
            :disabled="ownUploadFileConfig.disabled || false"
            :show-file-list="false"
            :before-upload="handleBeforeUpload"
            :on-change="handleChange"
            :on-success="handleSuccess"
            :on-exceed="handleExceed"
            :on-remove="handleRemove"
            :on-error="handleError"
        >
            <el-icon class="el-icon--upload"><upload-filled /></el-icon>
            <div class="el-upload__text">
                <span>{{ownUploadFileConfig.uploadText || "拖入此处上传或点击上传"}}</span>
                <div>{{ownUploadFileConfig.fileTypeText || "（支持xls、word、pdf文件格式）"}}</div>
            </div>
        </el-upload>
        <div class="QilinUploadFile-list">
            <div class="QilinUploadFile-list-item"
                v-for="(item,index) in ownUploadFileConfig.fileList"
                :key="item[ownUploadFileConfig.fileOptions?.serverUrl || 'fileName'] || 'filelist-key'+index"
            >
                <el-icon><Document /></el-icon>
                <span @click="ownUploadFileConfig.previewFn && ownUploadFileConfig.previewFn(item)">
                    {{item[ownUploadFileConfig.fileOptions?.serverName || 'newFileName']}}
                </span>
                <el-icon @click="ownUploadFileConfig.downloadFn && ownUploadFileConfig.downloadFn(item)" title="下载"><Download /></el-icon>
                <el-icon @click="deleteFile(index,item)" title="删除"><Delete /></el-icon>
            </div>
        </div>
    </div>
</template>

<script setup>
import {defineOptions,computed,ref,nextTick} from "vue";
import {ElMessage} from "element-plus";
import Qilin from "qilin-utils";

defineOptions({
    name:"QilinUploadFile"
});

/*
    数据变量定义区域
*/
// 获取上传文件元素DOM
const uploadFileRef=ref(null);
// 原始文件列表--用以删除
let uploadFilesList = ref([]);


/*
    计算属性等代码区域
*/
// 接收父组件传来的值
const propsValue=defineProps({
    uploadFileConfig:{
        type:Object,
        default(){
            return {
                // 组件自身的默认配置
                action:"#", //文件上传至服务器url
                headers:{}, //设置上传的请求头部--当action有值时必填，用以设置token等
                listType:"text", //文件列表类型
                autoUpload:false, //是否自动上传，当action有值时，则autoUpload须为true
                limit:5, //文件允许上传数量
                fileList:[], //默认上传文件--必填
                multiple:true, //是否支持多选文件
                drag:true, //是否启用拖拽上传
                disabled:false, //是否禁用上传
                uploadText:"拖入此处上传或点击上传", //上传文字说明
                fileTypeText:"（支持xls、word、pdf文件格式）", //支持格式文字说明
                fileType:["xls","xlsx","doc","docx","pdf"], //支持上传的文件类型
                fileSize:20 * 1000 * 1000, //文件上传大小限制20M之内默认
                previewFn:"event", //点击文件名称触发事件
                downloadFn:"event", //点击文件下载图标触发事件
                fileOptions:{ //文件设置配置项
                    serverOriginalName:"originalFilename", //文件上传至后端，返回的原始文件名称
                    serverName:"newFileName", //文件上传至后端，返回的文件名称--用以回显文件的名称
                    serverUrl:"fileName", //文件上传至后端，返回的文件url地址--用以回显文件的url
                    responseDataName:"data", //文件上传至服务器，返回的响应字段，默认为data，通常也是data
                }
            };
        }
    },
    fileList:{ //用以回显
        type:[Array,String],
        default(){
            return []
        }
    }
});

// 暴露父组件自定义方法
const emits=defineEmits(["update:uploadFileConfig","success","actionSuccess"]);

// 组件自身的配置项
let ownUploadFileConfig=computed({
    get(){
        // propsValue.uploadFileConfig.fileList=Qilin.Common.deepCopy(propsValue.fileList ? ( typeof propsValue.fileList === "string" ? JSON.parse(propsValue.fileList) : propsValue.fileList || [] ) : [] , []);
        propsValue.uploadFileConfig.fileList=propsValue.fileList ? ( typeof propsValue.fileList === "string" ? JSON.parse(propsValue.fileList) : propsValue.fileList || [] ) : [];
        return propsValue.uploadFileConfig;
    },
    set(val){
        emits("update:uploadFileConfig",val);
    }
});


/*
    逻辑脚本代码区域
*/
/**
 *  **当action为指定服务器地址时
 */
// 文件上传之前的事件监听
const handleBeforeUpload=(file)=>{
    // console.log(file,ownUploadFileConfig.value.action);
    if(!ownUploadFileConfig.value.action || ownUploadFileConfig.value.action === "#") return ;
    const index=file.name.lastIndexOf(".");
    const fileType=file.name.slice(index+1).toLowerCase();
    if(ownUploadFileConfig.value.fileType && !ownUploadFileConfig.value.fileType.includes(fileType)){
        ElMessage({
            message:"请上传符合格式要求的文件",
            type:"warning"
        });
        return false;
    }else if(!ownUploadFileConfig.value.fileType && !["xls","xlsx","doc","docx","pdf"].includes(fileType)){
        ElMessage({
            message:"请上传符合格式要求的文件",
            type:"warning"
        });
        return false;
    }else if(file.size > (ownUploadFileConfig.value.fileSize || 20 * 1000 * 1000)){
        ElMessage({
            message:"文件大小超过限制",
            type:"warning"
        });
        return false;
    };
};
// 文件上传成功后的事件监听
const handleSuccess=(response,uploadFile,uploadFiles)=>{
    // console.log(response,uploadFile,uploadFiles,"========");
    emits("actionSuccess",response,uploadFile);
};
// 文件上传失败后的事件监听
const handleError=(error,uploadFile,uploadFiles)=>{
    // console.log(error,uploadFile,uploadFiles,"========");
    nextTick(()=>{
        uploadFileRef.value.handleRemove(uploadFile);
    });
};

/**
 *  **当action未填写时
 */
// 文件上传状态改变事件监听
const handleChange=(file,files)=>{
    // console.log(file,files);
    if(ownUploadFileConfig.value.action) return ;
    const index=file.name.lastIndexOf(".");
    const fileType=file.name.slice(index+1).toLowerCase();
    if(ownUploadFileConfig.value.fileType && !ownUploadFileConfig.value.fileType.includes(fileType)){
        ElMessage({
            message:"请上传符合格式要求的文件",
            type:"warning"
        });
        nextTick(()=>{
            uploadFileRef.value.handleRemove(file);
        });
    }else if(!ownUploadFileConfig.value.fileType && !["xls","xlsx","doc","docx","pdf"].includes(fileType)){
        ElMessage({
            message:"请上传符合格式要求的文件",
            type:"warning"
        });
        nextTick(()=>{
            uploadFileRef.value.handleRemove(file);
        });
    }else if(file.size > (ownUploadFileConfig.value.fileSize || 20 * 1000 * 1000)){
        ElMessage({
            message:"文件大小超过限制",
            type:"warning"
        });
        nextTick(()=>{
            uploadFileRef.value.handleRemove(file);
        });
    }else{
        uploadFilesList.value.push(file);
        ownUploadFileConfig.value.fileList.push({
            raw:file.raw,
            name:file.name
        });
        emits("success",ownUploadFileConfig.value.fileList,file);
    };
};

// 超出限制时的事件监听
const handleExceed=(files,uploadFiles)=>{
    // console.log(files,uploadFiles,ownUploadFileConfig.value.fileList,"============");
    ElMessage({
        message:"文件上传数量不能大于"+(ownUploadFileConfig.value.limit || 5 )+"个",
        type:"warning"
    });
};
// 移除文件时的事件监听
const handleRemove=(uploadFile,uploadFiles)=>{
    // console.log(uploadFile,uploadFiles);
};
// 点击删除文件图标事件监听
const deleteFile=(index,item)=>{
    const deleteFileItem = uploadFilesList.value.find((item1)=>{
        return item[ownUploadFileConfig.value.fileOptions?.serverOriginalName || "originalFilename"] === item1.name;
    });
    if(deleteFileItem) uploadFileRef.value.handleRemove(deleteFileItem);
    ownUploadFileConfig.value.fileList.splice(index,1);
    emits("success",ownUploadFileConfig.value.fileList,index);
};


/*
    生命周期等代码区域
*/

</script>

<style lang="scss" scoped>
.el-upload{
    >.el-upload-dragger{
        .el-icon{
            font-size:32px;
            margin-bottom:0;
        }
    }
    .el-upload__text{
        >span{
            color:$text-color-65;
            font-size:$small-text-size;
        }
        >div{
            color:$text-color-45;
            font-size:$small-text-size;
            line-height:20px;
        }
    }
}
.QilinUploadFile{
    width:100%;
    >div:first-child{
        width:65%;
    }
    >.QilinUploadFile-list{
        width:65%;
        >.QilinUploadFile-list-item{
            display:flex;
            align-items:center;
            justify-content: space-between;
            margin:10px 0;
            line-height:1.5;
            >span{
                color:$primary-text-color;
                margin:0 6px;
                cursor:pointer;
                flex:1;
                min-width:0;
                white-space:nowrap;
                overflow:hidden;
                text-overflow:ellipsis;
            }
            >.el-icon{
                color:$primary-text-color;
                margin:0 5px;
                cursor:pointer;
            }
        }
    }
}
</style>
